/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.yonsei.iwb.sdt.guix;

import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ResIterator;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.vocabulary.OWL;
import com.hp.hpl.jena.vocabulary.RDF;
import com.hp.hpl.jena.vocabulary.RDFS;
import java.util.Vector;
import org.yonsei.iwb.sdt.SDTLearner;
import org.yonsei.iwb.sdt.SDTLearningType;
import org.yonsei.iwb.sdt.SDTSearcher;
import org.yonsei.iwb.sdt.datastructure.rule.DecisionRule;
import org.yonsei.iwb.sdt.datastructure.rule.DecisionRuleSet;
import org.yonsei.iwb.sdt.datastructure.tree.DNode;
import org.yonsei.iwb.sdt.ontology.JenaModelType;
import org.yonsei.iwb.sdt.ontology.OntologyModel;
import org.yonsei.iwb.sdt.util.SDTLog;
import org.yonsei.iwb.sdt.util.UtilFunctions;

/**
 *
 * @author DK
 */
public class Controller {

    private GDLearningPanel mf;
    private String ontology;
    private OntologyModel ontmodel;
    private int learningType = SDTLearningType.DEFAULT;
    private double threshold = 0;
    private Resource targetClass;
    private Resource targetProperty;
    private Model model;
    private SDTLearner sdtl;
    private SDTSearcher sdts;
    private DNode root;
    private GraphDataLearner gdl;
    private Vector<Resource> posset;
    private Vector<Resource> negset;

    public Controller(GraphDataLearner gdl) {
//    public Controller(MainFrame mf){        
        this.gdl = gdl;

    }

    public Model getJenaModel() {
        return this.model;
    }

    public void setPOSNEG_Instances(Vector<String> pos, Vector<String> neg) {

//        SDTLog.log(SDTLog.DETAIL, "Positive Instances:\n");                
        StringBuffer ps = new StringBuffer();
        StringBuffer ns = new StringBuffer();
        this.posset = new Vector<Resource>();
        this.negset = new Vector<Resource>();
        for (int i = 0; i < pos.size(); i++) {
            Resource posr = this.model.createResource(pos.get(i));
            this.posset.add(posr);
            ps.append(posr.toString() + "\n");
        }

        for (int i = 0; i < neg.size(); i++) {
            Resource negr = this.model.createResource(neg.get(i));
            this.negset.add(negr);
            ns.append(negr.toString() + "\n");
        }

//        SDTLog.log(SDTLog.DETAIL, ps.append(ns));      

    }

    public void selectOntFile(String ontology) {
        this.ontology = ontology;
    }
    
    public Vector<String> getAllInstances(){
        Vector<String> instanceSet = new Vector();
        
        ResIterator res = this.model.listResourcesWithProperty(RDF.type, OWL.Class);
        while (res.hasNext()) {
            Resource r = res.nextResource();
            ResIterator insset = this.model.listResourcesWithProperty(RDF.type, r);
            while(insset.hasNext()){
                String s = insset.nextResource().toString();
                if(!instanceSet.contains(s)){
                    instanceSet.add(s);
                }
            }
            
        }
        
        return instanceSet;
    }

    public Vector<String> getClassTypeResource() {
        Vector<String> classSet = new Vector<String>();

        ResIterator res = this.model.listResourcesWithProperty(RDF.type, OWL.Class);

        while (res.hasNext()) {
            String s = res.nextResource().toString();
            classSet.add(s);
        }

        return classSet;
    }

    public Vector<String> getPropertyResource(String classuri) {
        Vector<String> propertySet = new Vector<String>();

        Resource r = this.model.createResource(classuri);
        ResIterator res = this.model.listResourcesWithProperty(RDFS.domain, r);
        while (res.hasNext()) {
            Resource p = res.nextResource();
//            StmtIterator stmt = this.model.listStatements(p, RDFS.range, XSD.xboolean);
//           
//            while(stmt.hasNext()){
//                Statement s = stmt.nextStatement();
            propertySet.add(p.toString());
//            }
        }
        return propertySet;
    }

    public void loadOntOnBaseDIR_TDB() {
//        JenaModelType.MODEL_DIR = directory;
        ontmodel = new OntologyModel(JenaModelType.TDB_MODEL);
        ontmodel.loadOntology(ontology);
        this.model = this.ontmodel.getJenaModel();
        printOntologyInfo();
    }

//    public void loadOntOnNEWDIR_TDB(String directory) {
//        JenaModelType.MODEL_DIR = directory;
//        ontmodel = new OntologyModel(JenaModelType.TDB_MODEL);
//        ontmodel.loadOntology(ontology);
//    }
    public void useExistTDBModel(String directory) {
        JenaModelType.MODEL_DIR = directory;
        ontmodel = new OntologyModel(JenaModelType.TDB_MODEL);
        this.model = this.ontmodel.getJenaModel();
        printOntologyInfo();
    }

    public void useOntOnMemory() {
        ontmodel = new OntologyModel(JenaModelType.MEMORY_MODEL);
        ontmodel.loadOntology(ontology);
        this.model = this.ontmodel.getJenaModel();
        printOntologyInfo();
    }
    
    public void printOntologyInfo(){
        Vector ins = new Vector();
        ResIterator res = this.model.listResourcesWithProperty(RDF.type, OWL.Class);
        System.out.println("class : " + res.toList().size());
        ResIterator rres = this.model.listResourcesWithProperty(RDF.type, OWL.Class);
        while(rres.hasNext()){
            
            Resource classr = rres.nextResource();
            ResIterator res4 = this.model.listResourcesWithProperty(RDF.type, classr);
            while(res4.hasNext()){
                Resource inst = res4.nextResource();
                if(!ins.contains(inst)){
                    ins.add(inst);                    
                }                
            }                        
        }
        ResIterator res2 = this.model.listResourcesWithProperty(RDF.type, OWL.ObjectProperty);        
        ResIterator res3 = this.model.listResourcesWithProperty(RDF.type, OWL.DatatypeProperty);
        System.out.println("property : " + (res2.toList().size() + res3.toList().size()));
        System.out.println("ins : " + ins.size());
        
        
    }

    public void setTargetClass(String s) {
        this.targetClass = this.model.createResource(s);
    }

    public void setTargetProperty(String s) {
        this.targetProperty = this.model.createResource(s);
    }

    public Vector<Resource> getTargetInstances() {
        ResIterator res = this.model.listResourcesWithProperty(RDF.type, this.targetClass);
        Vector<Resource> tiset = UtilFunctions.getSubjectResourceVector(res);
        return tiset;
    }

    public void setThreshold(double e) {
        this.threshold = e;
    }

    public void setLearningType(int e) {
        this.learningType = e;
    }

    public void defineSDTLearner(int type, GDLearningPanel gdlp) {
        if (type == CurrentMainFrameStatus.TARGET_PROPERTY_USED) {
            
            this.sdtl = new SDTLearner(this.targetClass.toString(), this.targetProperty.toString(), this.ontmodel, this.learningType);
//            SDTLog.setLogType(SDTLog.BASIC);
            this.sdtl.setENTROPY_THRESHOLD(this.threshold);
            this.root = sdtl.learningStart();
            gdlp.svp.showGraph(this.root);

        } else if (type == CurrentMainFrameStatus.TARGET_INSTANCE_USED) {
//            this.sdtl = new SDTLearner(this.targetClass.toString(), this.posset, this.negset, this.ontmodel, this.learningType);
            this.sdtl = new SDTLearner(this.posset, this.negset, this.ontmodel, this.learningType);
//            SDTLog.setLogType(SDTLog.BASIC);
            this.sdtl.setENTROPY_THRESHOLD(this.threshold);
            this.root = sdtl.learningStart(true);
            gdlp.svp.showGraph(this.root);
        }

    }

    public void defineSDTSearcher() {
        if (this.sdts == null) {
            this.sdts = new SDTSearcher(this.model);
        }
    }

    public Vector<Resource> getMatcherResourceSet(DecisionRule dr) {
        return this.sdts.getRuleMatcherInstanceSet(dr, new Vector<Resource>());
    }

    public Vector<Resource> getMatcherResourceSet(DecisionRule dr, Vector<Resource> rset) {
        return this.sdts.getRuleMatcherInstanceSet(dr, rset);
    }

    public DecisionRuleSet getDecisionRuleSet() {
        return this.sdtl.getDecisionRuleSet();
    }
}
